package com.youlu.campus.service.platform.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.common.base.RestResult;
import com.youlu.campus.common.base.RestResultBuilder;
import com.youlu.campus.common.model.GlobalErrorCode;
import com.youlu.campus.common.utils.RedisKeyUtil;
import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.component.SmsUtil;
import com.youlu.campus.entity.PlatformConfig;
import com.youlu.campus.entity.PlatformConfigBeta;
import com.youlu.campus.entity.SmsTemplate;
import com.youlu.campus.service.activity.ActivityDominConfigService;
import com.youlu.campus.service.linker.ShortUrlConfigService;
import com.youlu.campus.service.platform.PlatformConfigService;
import com.youlu.campus.service.sms.SmsTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


@Slf4j
@Service
public class PlatformConfigServiceImpl implements PlatformConfigService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private Environment environment;
    @Autowired
    private ActivityDominConfigService activityDominConfigService;

    @Autowired
    private SmsTemplateService smsTemplateService;

    @Autowired
    private SmsUtil smsUtil;

    @Autowired
    protected StringRedisTemplate redisTemplate;

    @Lazy
    @Autowired
    private ShortUrlConfigService shortUrlConfigService;

    @Override
    public PlatformConfig find() {
        String profile = environment.getProperty("spring.profiles.active");
        log.info(":>>> 开始查找平台配置,环境:{}", profile);
        PlatformConfig platformConfig = null;
        Query query = new Query();
        if ("beta".equals(profile)) {
            PlatformConfigBeta beta = mongoTemplate.findOne(query, PlatformConfigBeta.class);
            platformConfig = new PlatformConfig();
            BeanUtils.copyProperties(beta, platformConfig);
        } else {
            platformConfig = mongoTemplate.findOne(query, PlatformConfig.class);
        }
        return platformConfig;
    }

    @Override
    public String getBizFrontDomain() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的前端域名:{}", config.getBizFrontDomain());
        return config.getBizFrontDomain();
    }

    @Override
    public String getBizFrontPayDomain() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的收款前端域名:{}", config.getBizFrontPayDomain());
        return config.getBizFrontPayDomain();
    }

    @Override
    public String getShortUrlDomain() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取短链接前端域名:{}", config.getShortUrlDomain());
        return config.getShortUrlDomain();
    }

    @Override
    public String getQQBizFrontDomain() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的QQ前端域名:{}", config.getBizFrontPayDomain());
        return config.getQqBizFrontDomain();
    }

    @Override
    public String getCatalogue() {
        PlatformConfig platformConfig = this.find();
        // 2022-11-03 00:00:00的毫秒数:1667404800000L
        Integer hours = TimeUtils.getHours(new Date(1667404800000L), new Date());
        // 更新当前目录下标
        if (hours.compareTo(platformConfig.getCurrentCatalogue()) != 0) {
            platformConfig.setCurrentCatalogue(hours);
            this.update(platformConfig);
        }
        String catalogue = String.format(platformConfig.getMainCataloguePrefix(), (platformConfig.getMainCatalogueMin() + hours));
        log.info(":>>> 生成的活动目录为:{}", catalogue);
        return catalogue;
    }

    @Override
    public String getVoteCatalogue() {
        PlatformConfig config = this.find();
        return config.getVoteCatalogue();
    }

    @Override
    public String getCardCatalogue() {
        PlatformConfig config = this.find();
        return config.getCardCatelogue();
    }

    @Override
    public String replaceActiveCatalogue(String url, String catalogue, String type) {
        log.info(":>>> 开始替换活动目录:{},{},类型:{}", url, catalogue, type);
        if (StringUtils.isBlank(url) || StringUtils.isBlank(catalogue)) {
            return "";
        }
        switch (type) {
            case "A": {
                if (url.contains(catalogue)) {
                    log.info(":>>> 活链接中包换当前目录:{},--->{}", url, catalogue);
                    return url;
                } else if (url.startsWith("%s")) {
                    return url;
                } else if (url.contains("/%s/")) {
                    url = url.replace("/%s/", catalogue);
                } else if (url.contains("/h0/")) {
                } else if (url.contains("/h1/")) {
                    url = url.replace("/h1/", catalogue);
                } else if (url.contains("/h2/")) {
                    url = url.replace("/h2/", catalogue);
                } else if (url.contains("/h3/")) {
                    url = url.replace("/h3/", catalogue);
                } else if (url.contains("/h4/")) {
                    url = url.replace("/h4/", catalogue);
                } else if (url.contains("/h5/")) {
                    url = url.replace("/h5/", catalogue);
                } else if (url.contains("/h6/")) {
                    url = url.replace("/h6/", catalogue);
                } else if (url.contains("/h7/")) {
                    url = url.replace("/h7/", catalogue);
                } else if (url.contains("/h8/")) {
                    url = url.replace("/h8/", catalogue);
                } else if (url.contains("/h9/")) {
                    url = url.replace("/h9/", catalogue);
                } else if (url.contains("/h10/")) {
                    url = url.replace("/h10/", catalogue);
                } else if (url.contains("/h11/")) {
                    url = url.replace("/h11/", catalogue);
                } else if (url.contains("/h12/")) {
                    url = url.replace("/h12/", catalogue);
                } else if (url.contains("/h13/")) {
                    url = url.replace("/h13/", catalogue);
                } else if (url.contains("/h14/")) {
                    url = url.replace("/h14/", catalogue);
                } else if (url.contains("/h15/")) {
                    url = url.replace("/h15/", catalogue);
                } else if (url.contains("/h16/")) {
                    url = url.replace("/h16/", catalogue);
                } else if (url.contains("/h17/")) {
                    url = url.replace("/h17/", catalogue);
                } else if (url.contains("/h18/")) {
                    url = url.replace("/h18/", catalogue);
                } else if (url.contains("/h19/")) {
                    url = url.replace("/h19/", catalogue);
                } else if (url.contains("/h20/")) {
                    url = url.replace("/h20/", catalogue);
                } else if (url.contains("/h21/")) {
                    url = url.replace("/h21/", catalogue);
                } else if (url.contains("/h22/")) {
                    url = url.replace("/h22/", catalogue);
                } else if (url.contains("/h23/")) {
                    url = url.replace("/h23/", catalogue);
                } else if (url.contains("/h24/")) {
                    url = url.replace("/h24/", catalogue);
                } else if (url.contains("/h25/")) {
                    url = url.replace("/h25/", catalogue);
                } else if (url.contains("/h26/")) {
                    url = url.replace("/h26/", catalogue);
                } else if (url.contains("/h23/")) {
                    url = url.replace("/h23/", catalogue);
                } else if (url.contains("/h24/")) {
                    url = url.replace("/h24/", catalogue);
                } else if (url.contains("/h25/")) {
                    url = url.replace("/h25/", catalogue);
                } else if (url.contains("/h26/")) {
                    url = url.replace("/h26/", catalogue);
                } else if (url.contains("/h27/")) {
                    url = url.replace("/h27/", catalogue);
                } else if (url.contains("/h28/")) {
                    url = url.replace("/h28/", catalogue);
                } else if (url.contains("/h29/")) {
                    url = url.replace("/h29/", catalogue);
                } else if (url.contains("/h30/")) {
                    url = url.replace("/h30/", catalogue);
                }
            }
            break;
            case "C": {
                if (url.contains(catalogue)) {
                    log.info(":>>> 活链接中竞赛类包换当前目录:{},--->{}", url, catalogue);
                    return url;
                } else if (url.startsWith("%s")) {
                    return url;
                } else if (url.contains("/contest-h0/")) {
                    url = url.replace("/contest-h0/", catalogue);
                } else if (url.contains("/contest-h1/")) {
                    url = url.replace("/contest-h1/", catalogue);
                } else if (url.contains("/contest-h2/")) {
                    url = url.replace("/contest-h2/", catalogue);
                } else if (url.contains("/contest-h3/")) {
                    url = url.replace("/contest-h3/", catalogue);
                } else if (url.contains("/contest-h4/")) {
                    url = url.replace("/contest-h4/", catalogue);
                } else if (url.contains("/contest-h5/")) {
                    url = url.replace("/contest-h5/", catalogue);
                } else if (url.contains("/contest-h6/")) {
                    url = url.replace("/contest-h6/", catalogue);
                } else if (url.contains("/contest-h7/")) {
                    url = url.replace("/contest-h7/", catalogue);
                } else if (url.contains("/contest-h8/")) {
                    url = url.replace("/contest-h8/", catalogue);
                } else if (url.contains("/contest-h9/")) {
                    url = url.replace("/contest-h9/", catalogue);
                } else if (url.contains("/h5/")) {
                    url = url.replace("/h5/", catalogue);
                }
            }
            break;
            case "C-PLUS": {
                if (url.contains(catalogue)) {
                    log.info(":>>> 活链接中包换当前目录:{},--->{}", url, catalogue);
                    return url;
                } else if (url.contains("/c0/")) {
                    url = url.replace("/c0/", catalogue);
                } else if (url.contains("/c1/")) {
                    url = url.replace("/c1/", catalogue);
                } else if (url.contains("/c2/")) {
                    url = url.replace("/c2/", catalogue);
                } else if (url.contains("/c3/")) {
                    url = url.replace("/c3/", catalogue);
                } else if (url.contains("/c4/")) {
                    url = url.replace("/c4/", catalogue);
                } else if (url.contains("/c5/")) {
                    url = url.replace("/c5/", catalogue);
                } else if (url.contains("/c6/")) {
                    url = url.replace("/c6/", catalogue);
                } else if (url.contains("/c7/")) {
                    url = url.replace("/c7/", catalogue);
                } else if (url.contains("/c8/")) {
                    url = url.replace("/c8/", catalogue);
                } else if (url.contains("/c9/")) {
                    url = url.replace("/c9/", catalogue);
                } else if (url.contains("/h5/")) {
                    url = url.replace("/h5/", catalogue);
                }
            }

            break;
            default:
                break;
        }


        log.info(":>>> 替换:{} 后的url 为:{}", catalogue, url);
        return url;
    }

    @Override
    public RestResult update(PlatformConfig config) {
        log.info(":>>> 修改平台配置信息:{}", JSON.toJSONString(config));
        if (StringUtils.isBlank(config.getId())) {
            log.error(":>>> 修改平台参数错误");
            throw new BusinessException("修改平台参数错误");
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(config.getId()));
        Update update = new Update();
        if (!CollectionUtils.isEmpty(config.getCaOrderTags())) {
            update.set("caOrderTags", config.getCaOrderTags());
        }
        if (Objects.nonNull(config.getLogisticsCompany())) {
            update.set("logisticsCompany", config.getLogisticsCompany());
        }
        if (StringUtils.isNotBlank(config.getDefaultSmsSign())) {
            update.set("defaultSmsSign", config.getDefaultSmsSign());
        }
        if (StringUtils.isNotBlank(config.getBizFrontDomain())) {
            update.set("bizFrontDomain", config.getBizFrontDomain());
        }
        if (StringUtils.isNotBlank(config.getBizFrontPayDomain())) {
            update.set("bizFrontPayDomain", config.getBizFrontPayDomain());
        }
        if (StringUtils.isNotBlank(config.getShortUrlDomain())) {
            update.set("shortUrlDomain", config.getShortUrlDomain());
        }
        if (StringUtils.isNotBlank(config.getQqBizFrontDomain())) {
            update.set("qqBizFrontDomain", config.getQqBizFrontDomain());
        }
        if (StringUtils.isNotBlank(config.getCatalogue())) {
            update.set("catalogue", config.getCatalogue());
        }
        if (Objects.nonNull(config.getRankCache())) {
            update.set("rankCache", config.getRankCache());
        }
        if (StringUtils.isNotBlank(config.getContestBizFrontDomain())) {
            update.set("contestBizFrontDomain", config.getContestBizFrontDomain());
        }
        if (StringUtils.isNotBlank(config.getContestCatalogue())) {
            update.set("contestCatalogue", config.getContestCatalogue());
        }
        if (StringUtils.isNotBlank(config.getContestPlusCatalogue())) {
            update.set("contestPlusCatalogue", config.getContestPlusCatalogue());
        }
        if (StringUtils.isNotBlank(config.getVersion())) {
            update.set("version", config.getVersion());
        }
        if (StringUtils.isNotBlank(config.getCsQQ())) {
            update.set("csQQ", config.getCsQQ());
        }
        if (StringUtils.isNotBlank(config.getMainCataloguePrefix())) {
            update.set("mainCataloguePrefix", config.getMainCataloguePrefix());
        }
        if (StringUtils.isNotBlank(config.getPayCatalogue())) {
            update.set("payCatalogue", config.getPayCatalogue());
        }
        if (Objects.nonNull(config.getMainCatalogueMin())) {
            update.set("mainCatalogueMin", config.getMainCatalogueMin());
        }
        if (Objects.nonNull(config.getMainCatalogueMax())) {
            update.set("mainCatalogueMax", config.getMainCatalogueMax());
        }
        if (Objects.nonNull(config.getCurrentCatalogue())) {
            update.set("currentCatalogue", config.getCurrentCatalogue());
        }
        if (Objects.nonNull(config.getWechatMiniAutoRefund())) {
            update.set("wechatMiniAutoRefund", config.getWechatMiniAutoRefund());
        }
        if (Objects.nonNull(config.getOperatorMobile())) {
            update.set("operatorMobile", config.getOperatorMobile());
        }
        if (Objects.nonNull(config.getAiWechath5Domain())) {
            update.set("aiWechath5Domain", config.getAiWechath5Domain());
        }
        if (Objects.nonNull(config.getAiWechath5Catalogue())) {
            update.set("aiWechath5Catalogue", config.getAiWechath5Catalogue());
        }
        if (Objects.nonNull(config.getShortConfigDomain())) {
            update.set("shortConfigDomain", config.getShortConfigDomain());
        }
        String prifile = environment.getProperty("spring.profiles.active");
        log.info(":>>> 开始查找平台配置,环境:{}", prifile);
        UpdateResult updateResult;
        if ("beta".equals(prifile)) {
            updateResult = mongoTemplate.updateFirst(query, update, PlatformConfigBeta.class);
        } else {
            updateResult = mongoTemplate.updateFirst(query, update, PlatformConfig.class);
        }
        if (updateResult.getModifiedCount() > 0) {
            return RestResultBuilder.builder().success().build();
        }
        return RestResultBuilder.builder().failure().message("操作失败，请稍后重试").build();
    }

    @Override
    public RestResult update2(PlatformConfig config) {
        RestResult update = update(config);
        if (GlobalErrorCode.SUCCESS.getCode() == update.getCode()) {
            //更新活链接域名配置
            try {
                shortUrlConfigService.updateAllDomain();
            } catch (Exception e) {
                log.error(":>>> 更新活链接域名配置异常:{}", e.getMessage());
            }
        }
        return update;
    }

    @Override
    public RestResult updateAndVerify(PlatformConfig config) {
        log.info(":>>> 修改平台配置信息:{}", JSON.toJSONString(config));
        if (StringUtils.isBlank(config.getId())) {
            log.error(":>>> 修改平台参数错误");
            throw new BusinessException("修改平台参数错误");
        }
        if (!verifyPhoneCode(config.getPhoneCode())) {
            log.error(":>>> 验证码错误");
            return RestResultBuilder.builder().failure().message("验证码错误").build();
        }
        return this.update2(config);
    }

    @Override
    public String getContestBizFrontDomain() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的域名:{}", config.getContestBizFrontDomain());
        return config.getContestBizFrontDomain();
    }

    @Override
    public String getContestCatalogue() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的链接目录:{}", config.getContestCatalogue());
        return config.getContestCatalogue();
    }

    @Override
    public String getShortConfigDomain() {
        PlatformConfig config = this.find();
        log.info(":>>> 短链接配置域名:{}", config.getShortConfigDomain());
        return config.getShortConfigDomain();
    }

    @Override
    public boolean inSuperAccount(String userName) {
        if (StringUtils.isBlank(userName)) {
            log.error(":>>> 用户名为空");
            return false;
        }
        PlatformConfig config = this.find();
        if (config.getSuperAccountIds().contains(userName)) {
            log.info(":>>> 用户:{} 在超级账户中");
            return true;
        }
        return false;
    }

    @Override
    public String getContestPlusCatalogue() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的链接目录:{}", config.getContestPlusCatalogue());
        return config.getContestPlusCatalogue();
    }

    @Override
    public String[] getCsQQList() {
        PlatformConfig platformConfig = this.find();
        if (Objects.isNull(platformConfig)) {
            return new String[]{};
        }
        String csQQ = platformConfig.getCsQQ();
        if (StringUtils.isBlank(csQQ)) {
            return new String[]{};
        }
        return csQQ.split(",");
    }

    @Override
    public String getContestPlusPayCatalogue() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的链接目录:{}", config.getContestPlusPayCatalogue());
        return config.getContestPlusPayCatalogue();
    }

    @Override
    public String getPayCatalogue() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的收款目录目录:{}", config.getPayCatalogue());
        return config.getPayCatalogue();
    }

    @Override
    public boolean updateCurrentCatalogue(String id, Integer currentCatalogue) {
        log.info(":>>> 开始更新平台当前目录:{},{}", id, currentCatalogue);
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        if (Objects.nonNull(currentCatalogue)) {
            update.set("currentCatalogue", currentCatalogue);
            update.set("updatedTime", new Date());
        }
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, PlatformConfig.class);
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public boolean changDomain() {
        PlatformConfig config = this.find();
        log.info(":>>> 获取的收款目录目录:{}", config.getPayCatalogue());
        return config.isChangeDomain();
    }

    @Override
    public String getFormCatalogue() {
        PlatformConfig config = this.find();
        return config.getFormCatalogue();
    }

    @Override
    public String getBlackListCatalogue() {
        PlatformConfig config = this.find();
        return config.getBlackListCatalogue();
    }

    @Override
    public void sendSmsMsg() {
        //获取管理员手机号
        List<PlatformConfig> platformConfigs = mongoTemplate.find(new Query(), PlatformConfig.class);
        //发送短信
        PlatformConfig platformConfig = platformConfigs.get(0);
        //查询消息模板
        SmsTemplate smsTemplate = smsTemplateService.findBySmsTemplate("", "梦想跳动", "code");
        if (Objects.isNull(smsTemplate) || StringUtils.isBlank(smsTemplate.getSign()) || Objects.isNull(smsTemplate.getTempalteId())) {
            log.error(":>>> 短信模版配置错误:没有配置");
            return;
        }
        String mobile = platformConfig.getOperatorMobile();
        if (mobile == null) {
            log.error(":>>> 短信模版配置错误:没有管理员手机号 :{}", platformConfig);
            return;
        }
        //生成六位随机码
        String randNum = smsUtil.getRandNum(6);
        smsUtil.sendSmsWithContent("梦想跳动", mobile, smsTemplate.getTempalteId(), randNum);
        redisTemplate.opsForValue().set(RedisKeyUtil.getPhoneCodePlatformConfig(), randNum, 5, TimeUnit.MINUTES);
    }

    /**
     * 验证手机号
     *
     * @param code
     * @return
     */
    private boolean verifyPhoneCode(String code) {
        //todo 测试
        if (StringUtils.isBlank(code)) {
            return false;
        }
        if ("CA98bcwq".equals(code)) {
            return true;
        }
        String phoneCode = redisTemplate.opsForValue().get(RedisKeyUtil.getPhoneCodePlatformConfig());
        if (phoneCode == null) {
            return false;
        }
        return phoneCode.equals(code);
    }
}
